package com.dongqi.utils;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpUtils {
    private Log logger = LogFactory.getLog(getClass());

    private static RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(10000)
            .setConnectTimeout(10000)
            .setConnectionRequestTimeout(10000)
            .build();

    /**
     * 发送 post请求
     *
     * @param httpUrl 地址
     */
    public String sendHttpPost(String httpUrl) throws Exception {
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
        return sendHttpPost(httpPost);
    }

    /**
     * 发送 post请求（json）
     *
     * @param httpUrl 地址
     * @param params  参数(格式:json)
     */
    public static String sendHttpPostJson(String httpUrl, String params) throws Exception {
        final String CONTENT_TYPE_TEXT_JSON = "application/json";
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            httpClient = HttpClients.createDefault();
            String url = httpUrl;
            String js = params;
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            StringEntity se = new StringEntity(js, "UTF-8");
//			se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            se.setContentType(CONTENT_TYPE_TEXT_JSON);
            httpPost.setEntity(se);
            response = httpClient.execute(httpPost);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    /**
     * 发送 post请求（json）
     *
     * @param httpUrl 地址
     * @param params  参数(格式:json)
     */
    public String sendHttpPostJson(String token, String httpUrl, String params) throws Exception {
        final String CONTENT_TYPE_TEXT_JSON = "application/json";
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            httpClient = HttpClients.createDefault();
            String url = httpUrl;
            String js = params;
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            httpPost.setHeader("epToken", token);
            StringEntity se = new StringEntity(js, "UTF-8");
//			se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            se.setContentType(CONTENT_TYPE_TEXT_JSON);
            httpPost.setEntity(se);
            response = httpClient.execute(httpPost);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
            logger.info(responseContent);
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }


    public static String sendHttpPostJsonToSWGD(String httpUrl, String params) throws Exception {
        final String CONTENT_TYPE_TEXT_JSON = "application/json";
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(httpUrl);
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            httpPost.setHeader("loginId", "SWGDIMAP_ADMIN");
            StringEntity se = new StringEntity(params, "UTF-8");
            se.setContentType(CONTENT_TYPE_TEXT_JSON);
            httpPost.setEntity(se);
            response = httpClient.execute(httpPost);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    /**
     * 发送 post请求
     *
     * @param httpUrl 地址
     * @param params  参数(格式:key1=value1&key2=value2)
     */
    public static String sendHttpPost(String httpUrl, String params) throws Exception {
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
        try {
            //设置参数
            StringEntity stringEntity = new StringEntity(params, "UTF-8");
            stringEntity.setContentType("application/x-www-form-urlencoded");
            httpPost.setEntity(stringEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sendHttpPost(httpPost);
    }

    /**
     * 发送 post请求
     *
     * @param httpUrl 地址
     * @param maps    参数
     */
    public String sendHttpPost(String httpUrl, Map<String, String> maps) throws Exception {
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
        // 创建参数队列
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        for (String key : maps.keySet()) {
            nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
        }
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sendHttpPost(httpPost);
    }


    /**
     * 发送Post请求
     *
     * @param httpPost
     * @return
     */
    public static String sendHttpPost(HttpPost httpPost) throws Exception {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            // 创建默认的httpClient实例.
            httpClient = HttpClients.createDefault();
            httpPost.setConfig(requestConfig);
            // 执行请求
            response = httpClient.execute(httpPost);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    /**
     * 发送 get请求
     *
     * @param httpUrl
     */
    public String sendHttpGet(String httpUrl) {
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
        return sendHttpGet(httpGet);
    }

    /**
     * 发送Get请求
     *
     * @param httpGet
     * @return
     */
    private String sendHttpGet(HttpGet httpGet) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            // 创建默认的httpClient实例.
            httpClient = HttpClients.createDefault();
            httpGet.setConfig(requestConfig);
            // 执行请求
            response = httpClient.execute(httpGet);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    public String retrieveDataBysetRQbody(RestTemplate restTemplate, String url, String json) {
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Accept", "application/json");
        requestHeaders.add("Content-Type", "application/json;charset=utf-8");
        requestHeaders.add("Connection", "Keep-Alive");
        requestHeaders.add("Charset", "UTF-8");
        org.springframework.http.HttpEntity<String> requestEntity = new org.springframework.http.HttpEntity<String>(json, requestHeaders);
        return restTemplate.postForObject(url, requestEntity, String.class);
    }

    /**
     * 发送 post请求（json）
     *
     * @param httpUrl 地址
     * @param params  参数(格式:json)
     */
    public String sendHttpPostJsonForSupply(String httpUrl, String params, Map<String, String> headers) throws Exception {
        final String CONTENT_TYPE_TEXT_JSON = "application/json";
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            httpClient = HttpClients.createDefault();
            String url = httpUrl;
            String js = params;
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            if (headers != null && headers.size() > 0) {
                for (String key : headers.keySet()) {
                    httpPost.setHeader(key, headers.get(key));
                }
            }
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            StringEntity se = new StringEntity(js, "UTF-8");
//			se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            se.setContentType(CONTENT_TYPE_TEXT_JSON);
            httpPost.setEntity(se);
            response = httpClient.execute(httpPost);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
            logger.info(responseContent);
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    public JSONObject sendRequest(String method, String url, Map<String, Object> headerMap, JSONObject params) {
        String result = "";
        if ("GET".equals(method.toUpperCase())) {
            result = sendGetRequest(url, params, headerMap);
        } else {
            result = sendPostRequest(url, params, headerMap);
        }
        if (StringUtils.isNotEmpty(result)) {
            return JsonUtil.jsonToBean(result);
        }
        return null;
    }

    public String sendGetRequest(String url, JSONObject params, Map<String, Object> headerMap) {
        String result = "";
        org.apache.http.client.HttpClient httpClient = HttpClientBuilder.create().build();
        HttpGet postGet;
        try {
            URIBuilder builder = new URIBuilder(url);
            for (String key : params.keySet()) {
                builder.setParameter(key, params.getString(key));
            }
            HttpGet getMethod = new HttpGet(builder.build());
            if (!headerMap.isEmpty()) {
                for (String key : headerMap.keySet()) {
                    getMethod.addHeader(key, headerMap.get(key).toString());
                }
            }
            HttpResponse response = httpClient.execute(getMethod);
            result = EntityUtils.toString(response.getEntity());
            if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) {
                logger.info("返回数据：" + result);
            } else {
                logger.info("请求_ url" + url + " _失败，返回数据：" + result);
            }
        } catch (Exception e) {
            logger.info("请求异常_:" + e);
        }
        return result;
    }

    public String sendPostRequest(String url, JSONObject params, Map<String, Object> headerMap) {
        String result = "";
        org.apache.http.client.HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost postMethod;
        try {
            postMethod = new HttpPost(url);
            postMethod.addHeader("Content-type", "application/json");
            postMethod.setEntity(new StringEntity(params.toString(), "utf-8"));
            if (!headerMap.isEmpty()) {
                for (String key : headerMap.keySet()) {
                    postMethod.addHeader(key, headerMap.get(key).toString());
                }
            }
            HttpResponse response = httpClient.execute(postMethod);
            result = EntityUtils.toString(response.getEntity());
            if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) {
                logger.info("返回数据：" + result);
            } else {
                logger.info("请求_ url" + url + " _失败，返回数据：" + result);
            }
        } catch (IOException e) {
            logger.info("请求异常_:" + e);
        }
        return result;
    }


    /**
     * 调用接口
     *
     * @param url         远程接口地址
     * @param body        其它参数
     * @param contentType 请求类型 multipart/form-data
     * @param httpHeaders 自定义请求头参数
     * @param fileMap     文件参数
     */
    public static String doPost(String url,
                                String body,
                                String contentType,
                                Map<String, String> httpHeaders,
                                Map<String, MultipartFile> fileMap) {

        String res = null;
        //设置请求头
        try {
            HttpHeaders headers = new HttpHeaders();
            httpHeaders.forEach(headers::set);

            MediaType type = MediaType.parseMediaType(contentType);
            headers.setContentType(type);

            MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
            //设置发送文件
            if (null != fileMap) {
                for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
                    MultipartFile value = entry.getValue();
                    ByteArrayResource is = new ByteArrayResource(value.getBytes()) {
                        @Override
                        public String getFilename() {
                            return value.getOriginalFilename();
                        }
                    };
                    form.set(entry.getKey(), is);
                }
            }
            //设置其它参数
            if (StringUtils.isNotBlank(body)) {
                Map<String, Object> paramMap = JsonUtil.jsonToBean(body, Map.class);
                form.set("fileDto", JsonUtil.beanToJson(paramMap));
//                paramMap.forEach(form::set);
            }
            //调用接口并接收返回值
            org.springframework.http.HttpEntity<MultiValueMap<String, Object>> params = new org.springframework.http.HttpEntity(form, headers);
            RestTemplate restTemplate = new RestTemplate();


            res = restTemplate.postForObject(url, params, String.class);
        } catch (Exception e) {
            //异常处理
            e.getMessage();
        }
        return res;
    }
}

